/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.animdemo.game;

import android.content.Context;
import android.os.Build;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManager;

import com.example.animdemo.AnimDemo;
import com.example.animdemo.R;
import com.example.animdemo.VectorPool;
import com.example.animdemo.base.AllocationGuard;
import com.example.animdemo.base.BaseObject;
import com.example.animdemo.base.DebugLog;
import com.example.animdemo.base.HudSystem;
import com.example.animdemo.base.ObjectManager;
import com.example.animdemo.input.InputSystem;
import com.example.animdemo.input.MultiTouchFilter;
import com.example.animdemo.input.SingleTouchFilter;
import com.example.animdemo.input.TouchFilter;
import com.example.animdemo.render.BufferLibrary;
import com.example.animdemo.render.CameraSystem;
import com.example.animdemo.render.ContextParameters;
import com.example.animdemo.render.DrawableBitmap;
import com.example.animdemo.render.DrawableFactory;
import com.example.animdemo.render.GLSurfaceView;
import com.example.animdemo.render.OpenGLSystem;
import com.example.animdemo.render.RenderSystem;
import com.example.animdemo.render.SpriteSheet;
import com.example.animdemo.render.Texture;
import com.example.animdemo.render.TextureLibrary;
import com.example.animdemo.rigidanim.RigidBody;
import com.example.animdemo.rigidanim.RigidObject;
import com.example.animdemo.rigidanim.RigidFactory;
import com.example.animdemo.rigidanim.RigidRenderComponent;
import com.example.animdemo.rigidanim.RigidSoul;

/**
 * High-level setup object for the AnimDemo game engine.
 * This class sets up the core game engine objects and threads.  It also passes events to the
 * game thread from the main UI thread.
 */
public class Game extends AllocationGuard {
	
	private GameThread mGameThread;
    private Thread mGame;
    private ObjectManager mGameRoot;
    
    private GameRenderer mRenderer;
    private GLSurfaceView mSurfaceView;
    private boolean mRunning;
    private boolean mBootstrapComplete;
    private boolean mGLDataLoaded;
    private ContextParameters mContextParameters;
    private TouchFilter mTouchFilter;
    
    public Game() {
        super();
        mRunning = false;
        mBootstrapComplete = false;
        mGLDataLoaded = false;
        mContextParameters = new ContextParameters();
    }

    /** 
     * Creates core game objects and constructs the game engine object graph.  Note that the
     * game does not actually begin running after this function is called (see start() below).
     * Also note that textures are not loaded from the resource pack by this function, as OpenGl
     * isn't yet available.
     * @param context
     */
    public void bootstrap(Context context, int viewWidth, int viewHeight, int gameWidth, int gameHeight, int difficulty) {
        if (!mBootstrapComplete) {
            mRenderer = new GameRenderer(context, this, gameWidth, gameHeight);
    
            // Create core systems
            BaseObject.sSystemRegistry.openGLSystem = new OpenGLSystem(null);
    
            
            ContextParameters params = mContextParameters;
            params.viewWidth = viewWidth;
            params.viewHeight = viewHeight;
            params.gameWidth = gameWidth;
            params.gameHeight = gameHeight;
            params.viewScaleX = (float)viewWidth / gameWidth;
            params.viewScaleY = (float)viewHeight / gameHeight;
            params.context = context;
            params.difficulty = difficulty;
            BaseObject.sSystemRegistry.contextParameters = params;
            
            final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
            if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
            	mTouchFilter = new SingleTouchFilter();
            } else {
            	mTouchFilter = new MultiTouchFilter();
            }
    
            // Short-term textures are cleared between levels.
            TextureLibrary shortTermTextureLibrary = new TextureLibrary();
            BaseObject.sSystemRegistry.shortTermTextureLibrary = shortTermTextureLibrary;
            
            // Long-term textures persist between levels.
            TextureLibrary longTermTextureLibrary = new TextureLibrary();
            BaseObject.sSystemRegistry.longTermTextureLibrary = longTermTextureLibrary;
            
            // The buffer library manages hardware VBOs.
            BaseObject.sSystemRegistry.bufferLibrary = new BufferLibrary();
    
            
            
            // The root of the game graph.
            MainLoop gameRoot = new MainLoop();
    
            InputSystem input = new InputSystem();
            BaseObject.sSystemRegistry.inputSystem = input;
            BaseObject.sSystemRegistry.registerForReset(input);
            
            WindowManager windowMgr = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 
            int rotationIndex = windowMgr.getDefaultDisplay().getOrientation(); 
            input.setScreenRotation(rotationIndex);

            GameObjectManager gameManager = new GameObjectManager(params.viewWidth * 2);
            BaseObject.sSystemRegistry.gameObjectManager = gameManager;
            
            GameObjectFactory objectFactory = new GameObjectFactory();
            BaseObject.sSystemRegistry.gameObjectFactory = objectFactory;

            
            CameraSystem camera = new CameraSystem();
            
    
            BaseObject.sSystemRegistry.cameraSystem = camera;
            BaseObject.sSystemRegistry.registerForReset(camera);
    
    
            gameRoot.add(gameManager);
    
            // Camera must come after the game manager so that the camera target moves before the camera 
            // centers.
            
            gameRoot.add(camera);
            
//            // Game Object
//            {
//            	final int BOTTOM_34 = 0;
//                final int BOTTOM = 1;
//                final int HAND = 2;
//                final int HEAD = 3;
//                final int HEAD_SIDE = 4;
//                final int SHOE_34 = 5;
//                final int SHOE = 6;
//                final int SHOE_SIDE = 7;
//                final int SHOE_UP = 8;
//                final int TOP_34 = 9;
//                final int TOP = 10;
//                
//                int[][] textureRegions = new int[][] {
//                	{159, 0, 61, 39}, 	// Bottom_34
//                	{66, 194, 68, 39}, 	// Bottom_front
//                	{87, 77, 21, 20}, 	// Hand
//                	{0, 98, 87, 95},	// Head_front
//                	{0, 0, 86, 97},		// Head_side
//                	{146, 40, 43, 34},	// Shoe_34
//                	{40, 194, 26, 42},	// Shoe_front
//                	{191, 40, 46, 29},  // Shoe_side
//                	{0, 194, 39, 42},	// Shoe_sidestep
//                	{221, 0, 32, 38},	// Shoe_up
//                	{87, 0, 58, 76},	// Top_34
//                	{88, 98, 70, 73},	// Top_front
//                };
//                
//                SpriteSheet sheet = new SpriteSheet(textureRegions);
//                Texture texture = BaseObject.sSystemRegistry.longTermTextureLibrary.allocateTexture(R.drawable.character_sprites);
//                
//                RigidBody body = RigidFactory.rigidBodyFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.character));
//                
//                RigidSoul soul = RigidFactory.rigidSoulFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.soul1));
//                
//                body.setSoul(soul);
//                
//                body.setTime(0.4f);
//                
//                RigidObject rigid = new RigidObject(body);
//                
//                RigidRenderComponent [] playerRCS = new RigidRenderComponent[] {
//                    	new RigidRenderComponent(0, sheet, texture, rigid),
//                    	new RigidRenderComponent(1, sheet, texture, rigid),
//                    	new RigidRenderComponent(7, sheet, texture, rigid),
//                    	new RigidRenderComponent(8, sheet, texture, rigid),
//                    	new RigidRenderComponent(9, sheet, texture, rigid),
//                    	new RigidRenderComponent(10, sheet, texture, rigid),
//                    	new RigidRenderComponent(11, sheet, texture, rigid),
//                    };
//                
//                GameObject player = new GameObject();
//                player.add(rigid);
//                for (int i = 0; i < playerRCS.length; i++) {
//                	player.add(playerRCS[i]);
//        		}
//                player.getPosition().set(-150, 0);
//                player.activationRadius = -1.0f;
//                
//                ObjectRegistry.sSystemRegistry.gameObjectManager.add(player);
//            }
//            
//         // Game Object
//            {
//            	final int BOTTOM_34 = 0;
//                final int BOTTOM = 1;
//                final int HAND = 2;
//                final int HEAD = 3;
//                final int HEAD_SIDE = 4;
//                final int SHOE_34 = 5;
//                final int SHOE = 6;
//                final int SHOE_SIDE = 7;
//                final int SHOE_UP = 8;
//                final int TOP_34 = 9;
//                final int TOP = 10;
//                
//                int[][] textureRegions = new int[][] {
//                	{159, 0, 61, 39}, 	// Bottom_34
//                	{66, 194, 68, 39}, 	// Bottom_front
//                	{87, 77, 21, 20}, 	// Hand
//                	{0, 98, 87, 95},	// Head_front
//                	{0, 0, 86, 97},		// Head_side
//                	{146, 40, 43, 34},	// Shoe_34
//                	{40, 194, 26, 42},	// Shoe_front
//                	{191, 40, 46, 29},  // Shoe_side
//                	{0, 194, 39, 42},	// Shoe_sidestep
//                	{221, 0, 32, 38},	// Shoe_up
//                	{87, 0, 58, 76},	// Top_34
//                	{88, 98, 70, 73},	// Top_front
//                };
//                
//                SpriteSheet sheet = new SpriteSheet(textureRegions);
//                Texture texture = BaseObject.sSystemRegistry.longTermTextureLibrary.allocateTexture(R.drawable.character_sprites);
//                
//                RigidBody body = RigidFactory.rigidBodyFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.character));
//                
//                RigidSoul soul = RigidFactory.rigidSoulFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.soul1));
//                
//                body.setSoul(soul);
//                
//                body.setTime(0.2f);
//                
//                RigidObject rigid = new RigidObject(body);
//                
//                RigidRenderComponent [] playerRCS = new RigidRenderComponent[] {
//                    	new RigidRenderComponent(0, sheet, texture, rigid),
//                    	new RigidRenderComponent(1, sheet, texture, rigid),
//                    	new RigidRenderComponent(7, sheet, texture, rigid),
//                    	new RigidRenderComponent(8, sheet, texture, rigid),
//                    	new RigidRenderComponent(9, sheet, texture, rigid),
//                    	new RigidRenderComponent(10, sheet, texture, rigid),
//                    	new RigidRenderComponent(11, sheet, texture, rigid),
//                    };
//                
//                GameObject player = new GameObject();
//                player.add(rigid);
//                for (int i = 0; i < playerRCS.length; i++) {
//                	player.add(playerRCS[i]);
//        		}
//                player.getPosition().set(50, 0);
//                player.activationRadius = -1.0f;
//                
//                ObjectRegistry.sSystemRegistry.gameObjectManager.add(player);
//            }
//            
//         // Game Object
//            {
//            	final int BOTTOM_34 = 0;
//                final int BOTTOM = 1;
//                final int HAND = 2;
//                final int HEAD = 3;
//                final int HEAD_SIDE = 4;
//                final int SHOE_34 = 5;
//                final int SHOE = 6;
//                final int SHOE_SIDE = 7;
//                final int SHOE_UP = 8;
//                final int TOP_34 = 9;
//                final int TOP = 10;
//                
//                int[][] textureRegions = new int[][] {
//                	{159, 0, 61, 39}, 	// Bottom_34
//                	{66, 194, 68, 39}, 	// Bottom_front
//                	{87, 77, 21, 20}, 	// Hand
//                	{0, 98, 87, 95},	// Head_front
//                	{0, 0, 86, 97},		// Head_side
//                	{146, 40, 43, 34},	// Shoe_34
//                	{40, 194, 26, 42},	// Shoe_front
//                	{191, 40, 46, 29},  // Shoe_side
//                	{0, 194, 39, 42},	// Shoe_sidestep
//                	{221, 0, 32, 38},	// Shoe_up
//                	{87, 0, 58, 76},	// Top_34
//                	{88, 98, 70, 73},	// Top_front
//                };
//                
//                SpriteSheet sheet = new SpriteSheet(textureRegions);
//                Texture texture = BaseObject.sSystemRegistry.longTermTextureLibrary.allocateTexture(R.drawable.character_sprites);
//                
//                RigidBody body = RigidFactory.rigidBodyFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.character));
//                
//                RigidSoul soul = RigidFactory.rigidSoulFrom(
//                		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.soul1));
//                
//                body.setSoul(soul);
//                
//                body.setTime(0.1f);
//                
//                RigidObject rigid = new RigidObject(body);
//                
//                RigidRenderComponent [] playerRCS = new RigidRenderComponent[] {
//                    	new RigidRenderComponent(0, sheet, texture, rigid),
//                    	new RigidRenderComponent(1, sheet, texture, rigid),
//                    	new RigidRenderComponent(7, sheet, texture, rigid),
//                    	new RigidRenderComponent(8, sheet, texture, rigid),
//                    	new RigidRenderComponent(9, sheet, texture, rigid),
//                    	new RigidRenderComponent(10, sheet, texture, rigid),
//                    	new RigidRenderComponent(11, sheet, texture, rigid),
//                    };
//                
//                GameObject player = new GameObject();
//                player.add(rigid);
//                for (int i = 0; i < playerRCS.length; i++) {
//                	player.add(playerRCS[i]);
//        		}
//                player.getPosition().set(150, 0);
//                player.activationRadius = -1.0f;
//                
//                ObjectRegistry.sSystemRegistry.gameObjectManager.add(player);
//            }
            spawnPlayer(-350, -100, 0.1f);
            spawnPlayer(-250, -100, 0.1f);
            spawnPlayer(-150, -100, 0.1f);
            spawnPlayer(-50, -100, 0.2f);
            spawnPlayer(50, -100, 0.3f);
            spawnPlayer(150, -100, 0.4f);
            spawnPlayer(250, -100, 0.5f);
            spawnPlayer(350, -100, 0.6f);
            
            spawnPlayer(-350 + 40, 100, 1.2f);
            spawnPlayer(-250 + 40, 100, 1.2f);
            spawnPlayer(-150 + 40, 100, 1.2f);
            spawnPlayer(-50 + 40, 100, 1.1f);
            spawnPlayer(50 + 40, 100, 1.0f);
            spawnPlayer(150 + 40, 100, 0.9f);
            spawnPlayer(250 + 40, 100, 0.8f);
            spawnPlayer(350 + 40, 100, 0.7f);
    
            // More basic systems.
            
            RenderSystem renderer = new RenderSystem();
            BaseObject.sSystemRegistry.renderSystem = renderer;
            BaseObject.sSystemRegistry.vectorPool = new VectorPool();
            BaseObject.sSystemRegistry.drawableFactory = new DrawableFactory();
          
            HudSystem hud = new HudSystem();
            
            Texture[] digitTextures = {
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_0),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_1),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_2),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_3),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_4),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_5),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_6),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_7),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_8),
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_9)
            };
            DrawableBitmap[] digits = {
                    new DrawableBitmap(digitTextures[0], 0, 0),
                    new DrawableBitmap(digitTextures[1], 0, 0),
                    new DrawableBitmap(digitTextures[2], 0, 0),
                    new DrawableBitmap(digitTextures[3], 0, 0),
                    new DrawableBitmap(digitTextures[4], 0, 0),
                    new DrawableBitmap(digitTextures[5], 0, 0),
                    new DrawableBitmap(digitTextures[6], 0, 0),
                    new DrawableBitmap(digitTextures[7], 0, 0),
                    new DrawableBitmap(digitTextures[8], 0, 0),
                    new DrawableBitmap(digitTextures[9], 0, 0)
            };
            DrawableBitmap xDrawable = new DrawableBitmap(
                    longTermTextureLibrary.allocateTexture(R.drawable.ui_x), 0, 0);
            
            hud.setDigitDrawables(digits, xDrawable);
            
            BaseObject.sSystemRegistry.hudSystem = hud;
            if (AnimDemo.VERSION < 0) {
            	hud.setShowFPS(true);
            }
            gameRoot.add(hud);
    
            mGameRoot = gameRoot;
            
            mGameRoot.commitUpdates();
            
            mGameThread = new GameThread(mRenderer);
            mGameThread.setGameRoot(mGameRoot);
    
            mBootstrapComplete = true;
        }
    }
    
    
    public void spawnPlayer(int x, int y, float time) {
    	
        final int BOTTOM_34 = 0;
        final int BOTTOM = 1;
        final int HAND = 2;
        final int HEAD = 3;
        final int HEAD_SIDE = 4;
        final int SHOE_34 = 5;
        final int SHOE = 6;
        final int SHOE_SIDE = 7;
        final int SHOE_UP = 8;
        final int TOP_34 = 9;
        final int TOP = 10;
        
        int[][] textureRegions = new int[][] {
        	{159, 0, 61, 39}, 	// Bottom_34
        	{66, 194, 68, 39}, 	// Bottom_front
        	{87, 77, 21, 20}, 	// Hand
        	{0, 98, 87, 95},	// Head_front
        	{0, 0, 86, 97},		// Head_side
        	{146, 40, 43, 34},	// Shoe_34
        	{40, 194, 26, 42},	// Shoe_front
        	{191, 40, 46, 29},  // Shoe_side
        	{0, 194, 39, 42},	// Shoe_sidestep
        	{221, 0, 32, 38},	// Shoe_up
        	{87, 0, 58, 76},	// Top_34
        	{88, 98, 70, 73},	// Top_front
        };
        
        SpriteSheet sheet = new SpriteSheet(textureRegions);
        Texture texture = BaseObject.sSystemRegistry.longTermTextureLibrary.allocateTexture(R.drawable.character_sprites);
        
        RigidBody body = RigidFactory.rigidBodyFrom(
        		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.character));
        
        RigidSoul soul = RigidFactory.rigidSoulFrom(
        		BaseObject.sSystemRegistry.contextParameters.context.getResources().openRawResource(R.raw.soul1));
        
        body.setSoul(soul);
        
        body.setTime(time);
        
        RigidObject rigid = new RigidObject(body);
        
        RigidRenderComponent [] playerRCS = new RigidRenderComponent[] {
            	new RigidRenderComponent(0, sheet, texture, rigid),
            	new RigidRenderComponent(1, sheet, texture, rigid),
            	new RigidRenderComponent(7, sheet, texture, rigid),
            	new RigidRenderComponent(8, sheet, texture, rigid),
            	new RigidRenderComponent(9, sheet, texture, rigid),
            	new RigidRenderComponent(10, sheet, texture, rigid),
            	new RigidRenderComponent(11, sheet, texture, rigid),
            };
        
        GameObject player = new GameObject();
        player.add(rigid);
        for (int i = 0; i < playerRCS.length; i++) {
        	player.add(playerRCS[i]);
		}
        player.getPosition().set(x, y);
        player.activationRadius = -1.0f;
        
        BaseObject.sSystemRegistry.gameObjectManager.add(player);
    }

    /** Starts the game running. */
    public void start() {
        if (!mRunning) {
            assert mGame == null;
            // Now's a good time to run the GC.
            Runtime r = Runtime.getRuntime();
            r.gc();
            DebugLog.d("AnimDemo", "Start!");
            mGame = new Thread(mGameThread);
            mGame.setName("Game");
            mGame.start();
            mRunning = true;
            AllocationGuard.sGuardActive = false;
        } else {
            mGameThread.resumeGame();
        }
    }
    
    public void stop() {
        if (mRunning) {
            DebugLog.d("AnimDemo", "Stop!");
            if (mGameThread.getPaused()) {
                mGameThread.resumeGame();
            }
            mGameThread.stopGame();
            try {
                mGame.join();
            } catch (InterruptedException e) {
                mGame.interrupt();
            }
            mGame = null;
            mRunning = false;
            AllocationGuard.sGuardActive = false;
        }
    }

    public boolean onTrackballEvent(MotionEvent event) {
        if (mRunning) {
        	if (event.getAction() == MotionEvent.ACTION_MOVE) {
        		BaseObject.sSystemRegistry.inputSystem.roll(event.getRawX(), event.getRawY());
        	} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
        		onKeyDownEvent(KeyEvent.KEYCODE_DPAD_CENTER);
        	} else if (event.getAction() == MotionEvent.ACTION_UP) {
        		onKeyUpEvent(KeyEvent.KEYCODE_DPAD_CENTER);
        	}
        }
        return true;
    }
    
    public boolean onOrientationEvent(float x, float y, float z) {
        if (mRunning) {
        	BaseObject.sSystemRegistry.inputSystem.setOrientation(x, y, z);
        }
        return true;
    }
        
    public boolean onTouchEvent(MotionEvent event) {
        if (mRunning) {
        	mTouchFilter.updateTouch(event);
        }
        return true;
    }
    
    public boolean onKeyDownEvent(int keyCode) {
        boolean result = false;
        if (mRunning) {
            BaseObject.sSystemRegistry.inputSystem.keyDown(keyCode);
        }
        return result;
    }
    
    public boolean onKeyUpEvent(int keyCode) {
        boolean result = false;
        if (mRunning) {
        	BaseObject.sSystemRegistry.inputSystem.keyUp(keyCode);
        }
        return result;
    }

    public GameRenderer getRenderer() {
        return mRenderer;
    }  
    
    public void onPause() {
    	if (mRunning) {
    		mGameThread.pauseGame(); 
    	}
    }
    
    public void onResume(Context context, boolean force) {
    	if (force && mRunning) {
    		mGameThread.resumeGame();
    	} else {
	        mRenderer.setContext(context);
	        // Don't explicitly resume the game here.  We'll do that in
	        // the SurfaceReady() callback, which will prevent the game
	        // starting before the render thread is ready to go.
	        BaseObject.sSystemRegistry.contextParameters.context = context;
    	}
    }
    
    
    
    public void onSurfaceReady() {
        DebugLog.d("AnimDemo", "Surface Ready");

        if (!mGLDataLoaded) {
            mSurfaceView.loadTextures(BaseObject.sSystemRegistry.longTermTextureLibrary);
            mSurfaceView.loadTextures(BaseObject.sSystemRegistry.shortTermTextureLibrary);
            mSurfaceView.loadBuffers(BaseObject.sSystemRegistry.bufferLibrary);
            mGLDataLoaded = true;
        }
        
        start();
        
        if (mGameThread.getPaused() && mRunning) {
            mGameThread.resumeGame();
        } 
    }
    
    public void setSurfaceView(GLSurfaceView view) {
        mSurfaceView = view;
    }
    
    public void onSurfaceLost() {
        DebugLog.d("AnimDemo", "Surface Lost");
        
        BaseObject.sSystemRegistry.shortTermTextureLibrary.invalidateAll();
        BaseObject.sSystemRegistry.longTermTextureLibrary.invalidateAll();
        BaseObject.sSystemRegistry.bufferLibrary.invalidateHardwareBuffers();

        mGLDataLoaded = false;
    }
    
    public void onSurfaceCreated() {
        DebugLog.d("AnimDemo", "Surface Created");
        
        // TODO: this is dumb.  SurfaceView doesn't need to control everything here.
        // GL should just be passed to this function and then set up directly.
        
        if (!mGLDataLoaded 
        		&& mGameThread.getPaused() 
        		&& mRunning) {
            mSurfaceView.loadTextures(BaseObject.sSystemRegistry.longTermTextureLibrary);
            mSurfaceView.loadTextures(BaseObject.sSystemRegistry.shortTermTextureLibrary);
            mSurfaceView.loadBuffers(BaseObject.sSystemRegistry.bufferLibrary);
            mGLDataLoaded = true;
        }
    }
    
	public void setSafeMode(boolean safe) {
		mSurfaceView.setSafeMode(safe);
	}
	
	public float getGameTime() {
		return BaseObject.sSystemRegistry.timeSystem.getGameTime();
	}
	

	public boolean isPaused() {
		return (mRunning && mGameThread != null && mGameThread.getPaused());
	}
}
